package com.example.service;

import com.example.common.Result;
import com.example.entity.Film;
import com.example.entity.Film;
import com.example.mapper.CommentMapper;
import com.example.mapper.FilmMapper;
import com.example.mapper.FilmMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.List;

import static java.util.Collections.shuffle;

@Service
public class FilmService {

    @Autowired
    private FilmMapper filmMapper;
    @Autowired
    private CommentMapper commentMapper;

    public List<Film> selectAll(Film film) {
        return filmMapper.selectAll(film);
    }

    public PageInfo<Film> selectByPage(Film film, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<Film> films = filmMapper.selectAll(film);
        for (Film f : films) {
            setScore(f);
        }
        return PageInfo.of(films);
    }

    public void add(Film film) {
        filmMapper.insert(film);
    }

    // 缓存Evict注解用于清除缓存，Cacheable注解用于缓存查询结果
    @CacheEvict(value = "filmDetail", key = "#film.id")
    public void update(Film film) {
        filmMapper.updateById(film);
    }

    // 缓存Evict注解用于清除缓存，Cacheable注解用于缓存查询结果
    @CacheEvict(value = "filmDetail", key = "#id")
    public void delete(Integer id) {
        filmMapper.deleteById(id);
    }

    // 缓存Evict注解用于清除缓存，Cacheable注解用于缓存查询结果
    @Cacheable(value = "filmDetail", key = "#id", unless = "#result == null")
    public Film selectById(Integer id) {
        Film film = filmMapper.selectById(id);
        setScore(film);
        return film;
    }

    public List<Film> selectRecommend(Integer id) {
         // 推荐算法
        List<Film> films = this.selectAll(null);
        // 排除自己
        films.removeIf(f -> f.getId().equals(id));
        // 随机打乱
        Collections.shuffle(films);
        // 取前三个
        List<Film> filmsRecommend = films.subList(0, 3);
        for (Film f : filmsRecommend) {
            setScore(f);
        }
        return filmsRecommend;
    }

    private void setScore(Film film) {
        int total = commentMapper.selectTotal(film.getId());
        film.setTotal(total);
        if (total == 0) {
            film.setScore(0D);
        } else {
            // 计算平均分
            double sum = commentMapper.selectSum(film.getId());
            BigDecimal score = BigDecimal.valueOf(sum).divide(BigDecimal.valueOf(total), 1, RoundingMode.HALF_UP);
            film.setScore(score.doubleValue());
        }
    }

    /**
     * 获取最受欢迎的5部电影
     * @param film
     * @return
     */
    public List<Film> selectTop5(Film film) {
        List<Film> films = this.selectAll(film);
        for (Film f : films) {
            setScore(f);
        }
        films.sort((f1, f2) -> f2.getScore().compareTo(f1.getScore()));
        return films.subList(0, 5);
    }
}
